package com.lee.pullrefresh.http;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.lee.pullrefresh.MyApplication;

public class NetUtils {
	private static final String TAG = "NetUtils";

	/**
	 * ��������ʹ�ô���Ĭ�ϣ������ж��û��Ƿ��ô���</br> false:ʹ��ֱ����ʽ��������</br>
	 * true:ʹ�õ�ǰ����IP��PORT��ʽ������
	 * 
	 */
	public static boolean isUseProxy = true;
	
	private static int connectionTimeout = 5000;
	private static int readTimeout = 100000;


	public static NetType getNetType() {

		NetType result = new NetType();// Ĭ��Ϊ������

		ConnectivityManager connectivityManager = null;
		try {
			connectivityManager = (ConnectivityManager) MyApplication.inst.getSystemService(Context.CONNECTIVITY_SERVICE);
		} catch (Exception e) {
		}

		if (null == connectivityManager) {
			return result;
		}

		if (!isNetworkAvailable(connectivityManager)) {
			return result;
		}

		int summaryType = getSummaryType(connectivityManager);

		NetworkInfo networkInfo = null;
		try {
			networkInfo = connectivityManager.getActiveNetworkInfo();
		} catch (Throwable e) {
		}

		String extraInfo = getExtraInfo(networkInfo);

		result = new NetType(summaryType, extraInfo);

		return result;
	}

	/**
	 * �ж��ǡ��ֻ����硱���ǡ��������硱
	 */
	public static int getSummaryType(ConnectivityManager connectivityManager) {

		int result = NetType.SUMMARY_TYPE_OTHER;

		// mobile
		State mobile = null;
		try {
			mobile = connectivityManager.getNetworkInfo(
					ConnectivityManager.TYPE_MOBILE).getState();
		} catch (Throwable e) {
		}
		// wifi
		State wifi = null;
		try {
			wifi = connectivityManager.getNetworkInfo(
					ConnectivityManager.TYPE_WIFI).getState();
		} catch (Throwable e) {
		}

		if (mobile == NetworkInfo.State.CONNECTED
				|| mobile == NetworkInfo.State.CONNECTING) {
			// mobile
			result = NetType.SUMMARY_TYPE_MOBILE;
		} else if (wifi == NetworkInfo.State.CONNECTED
				|| wifi == NetworkInfo.State.CONNECTING) {
			// wifi
			result = NetType.SUMMARY_TYPE_WIFI;
		}

		return result;
	}

	/**
	 * ���������Ϣ
	 */
	public static String getExtraInfo(NetworkInfo networkInfo) {
		String result = "";
		try {
			result = networkInfo.getExtraInfo();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * �ж��Ƿ������磨����NetworkInfo��
	 */

	/**
	 * ������������Ƿ����
	 * 
	 * @param ctx
	 * @return true ����; false ������
	 */
	final public static boolean isNetworkAvailable() {
		ConnectivityManager connectivity = (ConnectivityManager) MyApplication.inst.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connectivity != null) {
			NetworkInfo[] info = connectivity.getAllNetworkInfo();
			if (info != null) {
				for (int i = 0; i < info.length; i++) {
					//if (info[i].getState() == NetworkInfo.State.CONNECTED) {
					if (info[i].isConnected()) {
						return true;
					}
				}
			}
		}
		return false;
	}
	
	private static boolean isNetworkAvailable(
			ConnectivityManager connectivityManager) {

		NetworkInfo[] networkInfos = null;
		try {
			networkInfos = connectivityManager.getAllNetworkInfo();
		} catch (Throwable e) {
		}
		if (networkInfos != null) {
			final int length = networkInfos.length;
			for (int i = 0; i < length; i++) {
				boolean connected = false;
				try {
					connected = networkInfos[i].getState() == NetworkInfo.State.CONNECTED;
				} catch (Throwable e) {
				}
				if (connected) {
					return true;
				}
			}
		}

		return false;
	}

	public static class NetType {

		public static final int NSP_CHINA_MOBILE = 1;// �ƶ�
		public static final int NSP_CHINA_UNICOM = 2;// ��ͨ
		public static final int NSP_CHINA_TELECOM = 3;// ����
		public static final int NSP_OTHER = 0;// ����
		public static final int NSP_NO = -1;// ������

		public static final int SUMMARY_TYPE_WIFI = 1;// WIFI
		public static final int SUMMARY_TYPE_MOBILE = 2;// MOBILE
		public static final int SUMMARY_TYPE_OTHER = 0;// ����

		private String extraInfo;

		private int summaryType = SUMMARY_TYPE_OTHER;
		private String detailType;

		Integer simState;
		String networkType;
		String networkTypeName;
		String networkOperator;
		String networkOperatorName;

		String proxyHost;
		Integer proxyPort;

		public NetType(int summaryType, String extraInfo) {
			this.summaryType = summaryType;
			this.extraInfo = extraInfo;
			getSimAndOperatorInfo();
		}

		public NetType() {
		}

		private void getSimAndOperatorInfo() {
			TelephonyManager telephonyManager = (TelephonyManager) MyApplication.inst
					.getSystemService(Context.TELEPHONY_SERVICE);
			try {
				simState = telephonyManager.getSimState();
			} catch (Throwable e) {
			}
			try {
				networkOperatorName = telephonyManager.getNetworkOperatorName();
			} catch (Throwable e) {
			}
			try {
				networkOperator = telephonyManager.getNetworkOperator();
			} catch (Throwable e) {
			}
			try {
				int temp = telephonyManager.getNetworkType();
				networkType = "" + temp;
				networkTypeName = getNetworkTypeName(temp);
			} catch (Throwable e) {
			}

		}

		public int getNSP() {

			if (null == simState
					|| simState == TelephonyManager.SIM_STATE_UNKNOWN) {
				return NSP_NO;
			}
			if (TextUtils.isEmpty(networkOperatorName)
					&& TextUtils.isEmpty(networkOperator)) {
				return NSP_NO;
			}

			if (("�й��ƶ�".equalsIgnoreCase(networkOperatorName))//
					|| ("CMCC".equalsIgnoreCase(networkOperatorName)) //
					|| ("46000".equalsIgnoreCase(networkOperator))//
					|| ("China Mobile".equalsIgnoreCase(networkOperatorName))) {
				// �й��ƶ�
				return NSP_CHINA_MOBILE;
			}
			if (("�й�����".equalsIgnoreCase(networkOperatorName))//
					|| ("China Telecom".equalsIgnoreCase(networkOperatorName))//
					|| ("46003".equalsIgnoreCase(networkOperator))) {
				// �й�����
				return NSP_CHINA_TELECOM;
			}
			if (("�й���ͨ".equalsIgnoreCase(networkOperatorName))//
					|| ("China Unicom".equalsIgnoreCase(networkOperatorName))//
					|| ("46001".equalsIgnoreCase(networkOperator))//
					|| ("CU-GSM".equalsIgnoreCase(networkOperatorName))) {
				// �й���ͨ
				return NSP_CHINA_UNICOM;
			}

			return NSP_OTHER;
		}

		public String getNetworkTypeName(int code) {
			switch (code) {
			case TelephonyManager.NETWORK_TYPE_GPRS:
				return "GPRS";
			case TelephonyManager.NETWORK_TYPE_EDGE:
				return "EDGE";
			case TelephonyManager.NETWORK_TYPE_UMTS:
				return "UMTS";
			case TelephonyManager.NETWORK_TYPE_HSDPA:
				return "HSDPA";
			case TelephonyManager.NETWORK_TYPE_HSUPA:
				return "HSUPA";
			case TelephonyManager.NETWORK_TYPE_HSPA:
				return "HSPA";
			case TelephonyManager.NETWORK_TYPE_CDMA:
				return "CDMA";
			case TelephonyManager.NETWORK_TYPE_EVDO_0:
				return "CDMA - EvDo rev. 0";
			case TelephonyManager.NETWORK_TYPE_EVDO_A:
				return "CDMA - EvDo rev. A";
			case TelephonyManager.NETWORK_TYPE_1xRTT:
				return "CDMA - 1xRTT";
			default:
				return "UNKNOWN";
			}
		}

		public String getDetailType() {
			// StringBuilder sb = new StringBuilder();
			return "";
		}

		public String getUploadType() {
			return networkType;
		}

		public String getProxyHost() {
			String proxyHost = android.net.Proxy.getDefaultHost();
			Log.d(TAG, "getProxyHost() proxyHost -->> " + proxyHost);

			if (SUMMARY_TYPE_WIFI == summaryType) {// �����л���WIFIʱproxyHost��Ȼ���л�ǰ���أ�������Ҫ��˴���
				Log.d(TAG, "getProxyHost() WIFI -->> ");
				return null;
			} else {
				Log.d(TAG, "getProxyHost() else -->> ");
				this.proxyHost = proxyHost;
				this.proxyPort = android.net.Proxy.getDefaultPort();
			}

			Log.d(TAG, "getProxyHost() proxyHost -->> " + proxyHost);
			return this.proxyHost;
		}

		public Integer getProxyPort() {
			return proxyPort;
		}

	}

	public static boolean is2GNetwork(Context context) {

		NetType netType = getNetType();
		if (netType.summaryType == NetType.SUMMARY_TYPE_WIFI) {
			return false;
		}

		TelephonyManager telephonyManager = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		int type = telephonyManager.getNetworkType();
		Log.d(TAG, "Net work type:" + type);
		if (TelephonyManager.NETWORK_TYPE_CDMA == type
				|| TelephonyManager.NETWORK_TYPE_GPRS == type
				|| TelephonyManager.NETWORK_TYPE_EDGE == type) {
			return true;
		}
		return false;
	}

	/**
	 * �ж��Ƿ���wifi����
	 * 
	 * @return
	 */
	public static boolean isWifi() {
		NetType netType = getNetType();
		if (netType.summaryType == NetType.SUMMARY_TYPE_WIFI) {
			return true;
		}
		return false;
	}

	/**
	 * ��ȡ�������ӣ�ȫ��ͳһ 2G������Ҫ�ߴ���
	 * 
	 * @param url
	 * @return
	 * @throws IOException
	 */
	public static HttpURLConnection getConncetion(String url) {
		HttpURLConnection conn = null;
		if (TextUtils.isEmpty(url))
			return conn;
		try {
			String proxyHost = null;
			Integer proxyPort = null;
			if (isUseProxy) {
				NetType netType = getNetType();
				proxyHost = netType.getProxyHost();
				proxyPort = netType.getProxyPort();
			}
			if (isUseProxy && null != proxyHost && null != proxyPort) {// ����ʽ
				Log.d(TAG, "use proxy  url:" + url + "- proxy -->> " + proxyHost+ "," + proxyPort);
				conn = (HttpURLConnection) new URL(url)
						.openConnection(new java.net.Proxy(
								java.net.Proxy.Type.HTTP,
								new InetSocketAddress(proxyHost, proxyPort)));
				
				//final Proxy proxy = new Proxy(Type.HTTP,InetSocketAddress.createUnresolved(proxyHost, proxyPort));
				//conn = (HttpURLConnection) new URL(url).openConnection(proxy);
				
			} else {// ֱ����ʽ
				isUseProxy = false;
				Log.d("HttpGroup", "no proxy url:" + url);
				conn = (HttpURLConnection) new URL(url).openConnection();
			}
			conn.setConnectTimeout(connectionTimeout);
			conn.setReadTimeout(readTimeout);
		} catch (MalformedURLException e) {
			e.printStackTrace();
			conn = null;
		} catch (IOException e) {
			e.printStackTrace();
			conn = null;
		}
		return conn;		
	}

	/**
	 * ��ȡHttpClient
	 * 
	 * @param params
	 * @return
	 */
	public static HttpClient getDefaultClient() {
		HttpParams params = new BasicHttpParams();
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
		HttpProtocolParams.setUseExpectContinue(params, true);
		/*
		 * HttpProtocolParams .setUserAgent( params,
		 * "Mozilla/5.0(Linux;U;Android 2.2.1;en-us;Nexus One Build.FRG83) "
		 * +
		 * "AppleWebKit/553.1(KHTML,like Gecko) Version/4.0 Mobile Safari/533.1"
		 * );
		 */

		HttpClient customerHttpClient = null;

		// ��ʱ����
		/* �����ӳ���ȡ���ӵĳ�ʱʱ�� */
		ConnManagerParams.setTimeout(params, 1000);
		/* ���ӳ�ʱ */
		HttpConnectionParams.setConnectionTimeout(params, 2000);
		/* ����ʱ */
		HttpConnectionParams.setSoTimeout(params, 4000);

		// �������ǵ�HttpClient֧��HTTP��HTTPS����ģʽ
		SchemeRegistry schReg = new SchemeRegistry();
		schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));

		// ʹ���̰߳�ȫ�����ӹ���������HttpClient
		ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
		customerHttpClient = new DefaultHttpClient(conMgr, params);
		
		String proxyHost = null;
		Integer proxyPort = null;
		if (isUseProxy) {
			NetType netType = getNetType();
			proxyHost = netType.getProxyHost();
			proxyPort = netType.getProxyPort();
		}
		if (isUseProxy && null != proxyHost && null != proxyPort) {// ����ʽ
			HttpHost proxy = new HttpHost(proxyHost, proxyPort);
			customerHttpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,proxy);
		} else {
			isUseProxy = false;
		}
		return customerHttpClient;

		
		
	}
}
